package serializer;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import entity.RpcRequest;
import enumeration.SerializerCode;
import enumeration.SerializerError;
import exception.SerializerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.rowset.serial.SerialException;
import java.io.IOException;

public class JsonSerializer implements Serializer {

    private static final Logger logger = LoggerFactory.getLogger(JsonSerializer.class);
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public int getCode() {
        return SerializerCode.JSON.getCode();
    }

    @Override
    public byte[] serialize(Object object) {
        byte[] bytes = new byte[0];
        try {
            bytes = objectMapper.writeValueAsBytes(object);
        } catch (JsonProcessingException e) {
            logger.error("Json 格式化出现错误",e);
            throw new SerializerException("Json 格式化出现错误");
        }
        return bytes;
    }

    @Override
    public Object deserialize(byte[] bytes, Class<?> clazz) {
        try {
            Object obj =  objectMapper.readValue(bytes,clazz);
            if (obj instanceof RpcRequest) {
                obj = handleRequest(obj);
            }
            return obj;
        } catch (IOException e) {
            logger.error("序列化时有错误发生:", e);
            throw new SerializerException("序列化时有错误发生");
        }
    }

    private Object handleRequest(Object obj) throws IOException {
        RpcRequest rpcRequest = (RpcRequest) obj;
        for (int i = 0; i < rpcRequest.getParameterTypes().length; i++) {
            Class<?> clazz = rpcRequest.getParameterTypes()[i];
            if (!clazz.isAssignableFrom(rpcRequest.getParameterTypes()[i].getClass())) {
                byte[] bytes = objectMapper.writeValueAsBytes(rpcRequest.getParameterTypes()[i]);
                rpcRequest.getParameterObjects()[i] = objectMapper.readValue(bytes,clazz);
            }
        }
        return rpcRequest;
    }

}
